1. Introduction
In this notebook, I examine the relationship between utterance
fluency (UF) measures and L2 speaking anxiety, addressing the following
three research questions (RQs):
RQ1: To what extent are speed fluency measures associated with
cognitive, somatic, and behavioral speaking anxiety?
RQ2: To what extent are breakdown fluency measures associated
with cognitive, somatic, and behavioral speaking anxiety?
RQ3: To what extent are repair fluency measures associated with
cognitive, somatic, and behavioral speaking anxiety?
In the following sections, I preprocess data, conduct preliminary
analyses, and construct regression models.
The following code block loads R packages required for analyses.
pacman::p_load(
tidyverse, here, skimr, psych,
PerformanceAnalytics, sjPlot, performance
)
2. Data Preprocess
This section tidies data. First of all, the following code block
loads data of UF measures.
df_uf_raw <- read.csv(here("data", "processed", "uf_measures.csv"))
The current analysis focuses on the UF measures shown in Table 1.
Table 1. UF Dimension and Corresponding Measures
| Speed Fluency (SF) |
Articulation Rate (AR) |
| Breakdown Fluency (BDF) |
Mid-Clause Pause Ratio (MCPR) |
|
End-Clause Pause Ratio (ECPR) |
|
Mid-Clause Pause Duration (MCPD) |
|
End-Clause Pause Duration (ECPD) |
| Repair Fluency (RF) |
Disfluency Ratio |
Thus, the following code block selects target measures. The code
block also renames the columns filename and
dysfluency_ratio to participant_id and
disfluency_ratio, respectively.
df_uf_raw %>%
select(
filename,
articulation_rate,
mid_clause_pause_ratio,
end_clause_pause_ratio,
mid_clause_p.dur,
end_clause_p.dur,
dysfluency_ratio
) %>%
rename(
participant_id = filename,
disfluency_ratio = dysfluency_ratio
) -> df_uf_tidy
df_uf_tidy
Next, the following code block loads data of post questionnaire about
anxiety and linguistic background.
df_questionnaire_raw <- read.csv(
here("data", "raw", "post_questionnaire.csv")
)
The following code block selects columns related to participant ID,
anxiety, L2 English proficiency, and other backgrounds and renames
them.
df_questionnaire_raw %>%
select(
参加者IDを入力してください.半角..,
英語を話すとき.私は言葉を間違えてしまうのではとしばしば心配になる.,
英語を話すとき.私は自分の話し方が他人より劣っているのではとしばしば心配になる.,
英語を話し始めるとすぐに.私は自分自身のことを表現できないのではと心配になり始める.,
英語を話すとき.私はドキドキすることがよくある.,
英語を話すとき.私は緊張でびくびくすることがよくある.,
英語を話すとき.私はよく汗をかいたり.発汗する.,
英語スピーキングの練習をするとき.私はしばしば.すぐに投げ出してしまう.,
私は英語スピーキングの練習の手を抜くことが多い.,
私は普段.極力英語を話さないようにしている.,
お持ちでしたら.英検のスコアを記入してください.,
お持ちでしたら.IELTS..Overall..のスコアを記入してください.,
お持ちでしたら.TOEFL.iBT.のスコアを記入してください.,
お持ちでしたら.TOEIC.のスコアを記入してください.,
性別,
年齢
) %>%
rename(
participant_id = 参加者IDを入力してください.半角..,
cognitive_anxiety_1 = 英語を話すとき.私は言葉を間違えてしまうのではとしばしば心配になる.,
cognitive_anxiety_2 = 英語を話すとき.私は自分の話し方が他人より劣っているのではとしばしば心配になる.,
cognitive_anxiety_3 = 英語を話し始めるとすぐに.私は自分自身のことを表現できないのではと心配になり始める.,
somatic_anxiety_1 = 英語を話すとき.私はドキドキすることがよくある.,
somatic_anxiety_2 = 英語を話すとき.私は緊張でびくびくすることがよくある.,
somatic_anxiety_3 = 英語を話すとき.私はよく汗をかいたり.発汗する.,
behavioral_anxiety_1 = 英語スピーキングの練習をするとき.私はしばしば.すぐに投げ出してしまう.,
behavioral_anxiety_2 = 私は英語スピーキングの練習の手を抜くことが多い.,
behavioral_anxiety_3 = 私は普段.極力英語を話さないようにしている.,
IELTS = お持ちでしたら.IELTS..Overall..のスコアを記入してください.,
TOEFL_IBT = お持ちでしたら.TOEFL.iBT.のスコアを記入してください.,
TOEIC = お持ちでしたら.TOEIC.のスコアを記入してください.,
eiken = お持ちでしたら.英検のスコアを記入してください.,
sex = 性別,
age = 年齢
) %>%
mutate(
sex = str_replace_all(sex, "男性", "male"),
sex = str_replace_all(sex, "女性", "female"),
eiken = str_replace_all(eiken, "準1級", "1.5"),
eiken = str_replace_all(eiken, "準1級", "1.5"),
eiken = str_replace_all(eiken, "2級", "2"),
eiken = str_replace_all(eiken, "1級", "1"),
eiken = str_replace_all(eiken, "英検4級", "4"),
eiken = as.numeric(eiken)
) -> df_questionnaire_tidy
df_questionnaire_tidy
3. Preliminary Analysis
3.1. Participant Background
The following code block calculates the descriptive statistics of
participants’ age.
df_questionnaire_tidy %>%
select(age) %>%
skim()
── Data Summary ────────────────────────
Values
Name Piped data
Number of rows 10
Number of columns 1
_______________________
Column type frequency:
numeric 1
________________________
Group variables None
The result showed that participants’ age was ranged \([20, 38]\), and their mean and SD were
\(28.8\) and \(5.613\).
The following code block counts sex of participants.
df_questionnaire_tidy %>%
group_by(sex) %>%
summarize(N = n())
The result indicated that there were equal number of male and female
participants.
3.2. Proficiency Levels
The following code block converts L2 English assessment scores to
CEFR.
cefr_levels = c("A1", "A2", "B1", "B2", "C1", "C2")
df_questionnaire_tidy %>%
select(participant_id, TOEFL_IBT, IELTS, TOEIC, eiken) %>%
mutate(
TOEFL_IBT = case_when(
TOEFL_IBT >= 114 ~ "C2",
TOEFL_IBT >= 95 ~ "C1",
TOEFL_IBT >= 72 ~ "B2"
),
IELTS = case_when(
IELTS >= 7 ~ "C1"
),
TOEIC = case_when(
TOEIC >= 945 ~ "C1",
TOEIC >= 785 ~ "B1",
TOEIC >= 550 ~ "B2"
),
eiken = case_when(
eiken >= 3 ~ "A1",
eiken >= 2 ~ "B1",
eiken >= 1.5 ~ "B2",
eiken >= 1 ~ "C1"
)
) %>%
mutate(
TOEFL_IBT = factor(TOEFL_IBT, levels = cefr_levels, order = T),
IELTS = factor(IELTS, levels = cefr_levels, order = T),
TOEIC = factor(TOEIC, levels = cefr_levels, order = T),
eiken = factor(eiken, levels = cefr_levels, order = T)
) %>%
replace_na(list(
TOEFL_IBT = "A1",
IELTS = "A1",
TOEIC = "A1",
eiken = "A1"
)) %>%
group_by(participant_id) %>%
summarize(CEFR = max(TOEFL_IBT, IELTS, TOEIC, eiken)) %>%
group_by(CEFR) %>%
summarize(N = n())
The result suggested that most participants were advanced-level L2
English learners (\(N=6\)), while other
four participants were intermediate-level English learners.
3.3. UF Measures
The following code block calculates the descriptive statistics of UF
measures.
df_uf_tidy %>%
select(-c(participant_id)) %>%
skim()
── Data Summary ────────────────────────
Values
Name Piped data
Number of rows 10
Number of columns 6
_______________________
Column type frequency:
numeric 6
________________________
Group variables None
3.4. Speaking Anxiety
The following code blocks calculate the reliability of anxiety
questionnaire answers in terms of Cronbach’s \(\alpha\).
3.4.1. Reliability of Cognitive Anxiety
df_questionnaire_tidy %>%
select(
cognitive_anxiety_1,
cognitive_anxiety_2,
cognitive_anxiety_3
) %>%
alpha()
Reliability analysis
Call: alpha(x = .)
95% confidence boundaries
Reliability if an item is dropped:
Item statistics
Non missing response frequency for each item
1 2 3 4 5 miss
cognitive_anxiety_1 0.0 0.3 0.1 0.3 0.3 0
cognitive_anxiety_2 0.1 0.1 0.0 0.6 0.2 0
cognitive_anxiety_3 0.2 0.3 0.0 0.2 0.3 0
The Cornbach’s \(\alpha\) of
cognitive anxiety questionnaires was \(.747\), indicating an acceptable internal
consistency
3.4.2. Reliability of Somatic Anxiety
df_questionnaire_tidy %>%
select(
somatic_anxiety_1,
somatic_anxiety_2,
somatic_anxiety_3
) %>%
alpha()
Reliability analysis
Call: alpha(x = .)
95% confidence boundaries
Reliability if an item is dropped:
Item statistics
Non missing response frequency for each item
1 2 3 4 5 miss
somatic_anxiety_1 0.2 0.3 0.1 0.2 0.2 0
somatic_anxiety_2 0.3 0.2 0.2 0.0 0.3 0
somatic_anxiety_3 0.3 0.3 0.0 0.4 0.0 0
The Cornbach’s \(\alpha\) of somatic
anxiety questionnaires was \(.900\),
indicating a excellent internal consistency.
3.4.3. Behavioral Anxiety
df_questionnaire_tidy %>%
select(
behavioral_anxiety_1,
behavioral_anxiety_2,
behavioral_anxiety_3
) %>%
alpha()
Reliability analysis
Call: alpha(x = .)
95% confidence boundaries
Reliability if an item is dropped:
Item statistics
Non missing response frequency for each item
1 2 3 4 5 miss
behavioral_anxiety_1 0.2 0.4 0.2 0.1 0.1 0
behavioral_anxiety_2 0.2 0.3 0.1 0.3 0.1 0
behavioral_anxiety_3 0.4 0.3 0.2 0.1 0.0 0
The Cornbach’s \(\alpha\) of somatic
anxiety questionnaires was \(.814\),
indicating a good internal consistency.
3.5. Correlations
This subsection conducts correlation analyses between UF measures and
speaking anxiety. Before the analyses, the following code block
calculates three anxiety scores by summing items and joins the two
dataframes.
df_questionnaire_tidy %>%
group_by(participant_id) %>%
summarize(
cognitive_anxiety = sum(
cognitive_anxiety_1, cognitive_anxiety_2, cognitive_anxiety_3
),
somatic_anxiety = sum(
somatic_anxiety_1, somatic_anxiety_2, somatic_anxiety_3
),
behavioral_anxiety = sum(
behavioral_anxiety_1, behavioral_anxiety_2, behavioral_anxiety_3
)
) %>%
inner_join(
df_uf_tidy, by = "participant_id"
) -> df_uf_anxiety
df_uf_anxiety
3.5.1. Correlations Among Anxiety Scores
The following code block generates a correlation matrix of three
anxiety scores.
df_uf_anxiety %>%
select(
cognitive_anxiety,
somatic_anxiety,
behavioral_anxiety
) %>%
chart.Correlation(histogram = T, method = "pearson", pch = 19)
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter

The result showed that significant strong correlation between
cognitive and somatic anxiety (\(r=.78\)). In addition, there was slightly
significant medium correlation between somatic and behavioral anxiety
(\(r=.59\)). Meanwhile, there was small
correlation between cognitive and behavioral anxiety (\(r=.48\)), but statistical significance was
not found.
3.5.2. Correlations Between UF Measures and Cognitive Anxiety
The following code block generates a correlation matrix of UF
measures and cognitive anxiety.
df_uf_anxiety %>%
select(-c(
participant_id,
somatic_anxiety,
behavioral_anxiety
)) %>%
chart.Correlation(histogram = T, method = "pearson", pch = 19)
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter

The result showed significant large correlation between cognitive
anxiety and ECPR, suggesting that participants produced end-clause
pauses more frequently when cognitive anxiety was lower.
3.5.3. Correlations Between UF Measures and Somatic Anxiety
The following code block generates a correlation matrix of UF
measures and somatic anxiety.
df_uf_anxiety %>%
select(-c(
participant_id,
cognitive_anxiety,
behavioral_anxiety
)) %>%
chart.Correlation(histogram = T, method = "pearson", pch = 19)
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter

The result did not show significant correlations between somatic
anxiety and UF measures.
3.5.4. Correlations Between UF Measures and Behavioral Anxiety
The following code block generates a correlation matrix of UF
measures and behavioral anxiety.
df_uf_anxiety %>%
select(-c(
participant_id,
cognitive_anxiety,
somatic_anxiety
)) %>%
chart.Correlation(histogram = T, method = "pearson", pch = 19)
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter

The result identified significant large correlations between
behavioral anxiety and MCPD (\(r=-.76\)) and ECPD (\(r=.79\)), suggesting that participants who
perceived lower behavioral anxiety generate longer MCPD and ECPD.
4. Regression Analyses
4.1. SF ~ Speaking Anxiety
The following code block constructs a regression model between AR and
speaking anxiety.
model_ar <- lm(
articulation_rate ~ cognitive_anxiety + somatic_anxiety + behavioral_anxiety,
df_uf_anxiety
)
The following code block shows the result.
tab_model(model_ar, digits = 3)
The result did not show significant relationship between three
anxiety scores and AR.
To examine the reliability of the current model, the following code
block conducts post-hoc analysis of regression assumptions.
check_model(model_ar)

The results suggested that the current model could be reliable.
4.2. BDF ~ Speaking Anxiety
4.2.1. MCPR ~ Speaking Anxiety
The following code block constructs a regression model between MCPR
and speaking anxiety.
model_mcpr <- lm(
mid_clause_pause_ratio ~ cognitive_anxiety + somatic_anxiety + behavioral_anxiety,
df_uf_anxiety
)
The following code block shows the result.
tab_model(model_mcpr, digits = 3)
The result did not show significant relationship between three
anxiety scores and MCPR.
To examine the reliability of the current model, the following code
block conducts post-hoc analysis of regression assumptions.
check_model(model_mcpr)

The results suggested that the current model could be less reliable
because the model could be affected by an outlier.
4.2.2. ECPR ~ Speaking Anxiety
The following code block constructs a regression model between ECPR
and speaking anxiety.
model_ecpr <- lm(
end_clause_pause_ratio ~ cognitive_anxiety + somatic_anxiety + behavioral_anxiety,
df_uf_anxiety
)
The following code block shows the result.
tab_model(model_ecpr, digits = 3)
The result showed slightly significant relationship between cognitive
anxiety and ECPR (\(p=.081\)). The
slope was \(-.003\) and suggested that
ECPR decreased \(.003\) when cognitive
anxiety increased \(1\).
To examine the reliability of the current model, the following code
block conducts post-hoc analysis of regression assumptions.
check_model(model_ecpr)

The results suggested that the current model could be reliable.
4.2.3. MCPD ~ Speaking Anxiety
The following code block constructs a regression model between MCPD
and speaking anxiety.
model_mcpd <- lm(
mid_clause_p.dur ~ cognitive_anxiety + somatic_anxiety + behavioral_anxiety,
df_uf_anxiety
)
The following code block shows the result.
tab_model(model_mcpd, digits = 3)
The result showed a significant link between behavioral anxiety and
MCPD (\(p=.025\)). The slope was \(-.074\), suggesting that MCPD became \(.074\) shorter when behavioral anxiety
score increased \(1\).
To examine the reliability of the current model, the following code
block conducts post-hoc analysis of regression assumptions.
check_model(model_mcpd)

The results suggested that the current model could be reliable.
4.2.4. ECPD ~ Speaking Anxiety
The following code block constructs a regression model between AR and
speaking anxiety.
model_enpd <- lm(
end_clause_p.dur ~ cognitive_anxiety + somatic_anxiety + behavioral_anxiety,
df_uf_anxiety
)
The following code block shows the result.
tab_model(model_enpd, digits = 3)
The result showed a significant link between behavioral anxiety and
MCPD (\(p=.020\)). The slope was \(-.072\), suggesting that ECPD became \(.072\) shorter when behavioral anxiety
score increased \(1\).
To examine the reliability of the current model, the following code
block conducts post-hoc analysis of regression assumptions.
check_model(model_enpd)

The results suggested that the current model could be reliable.
4.3. RF ~ Speaking Anxiety
The following code block constructs a regression model between DR and
speaking anxiety.
model_dr <- lm(
disfluency_ratio ~ cognitive_anxiety + somatic_anxiety + behavioral_anxiety,
df_uf_anxiety
)
The following code block shows the result.
tab_model(model_dr, digits = 3)
The result did not show significant relationship between three
anxiety scores and DR.
To examine the reliability of the current model, the following code
block conducts post-hoc analysis of regression assumptions.
check_model(model_dr)
Quitting from lines 526-527 [unnamed-chunk-35] (final_report_analysis.Rmd)

The results suggested that the current model could be less reliable
because the model could be affected by an outlier.
LS0tCnRpdGxlOiAnSW50cm9SOiBGaW5hbCBSZXBvcnQgQW5hbHlzaXMnCmF1dGhvcjogIlJ5dWtpIE1hdHN1dXJhIgpkYXRlOiAiMjAyNC8xMS8yNyIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIGRmX3ByaW50OiBwYWdlZAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgdGhlbWU6IGZsYXRseQotLS0KCiMjIDEuIEludHJvZHVjdGlvbgoKSW4gdGhpcyBub3RlYm9vaywgSSBleGFtaW5lIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB1dHRlcmFuY2UgZmx1ZW5jeSAoVUYpIG1lYXN1cmVzIGFuZCBMMiBzcGVha2luZyBhbnhpZXR5LCBhZGRyZXNzaW5nIHRoZSBmb2xsb3dpbmcgdGhyZWUgcmVzZWFyY2ggcXVlc3Rpb25zIChSUXMpOgoKLSAgIFJRMTogVG8gd2hhdCBleHRlbnQgYXJlIHNwZWVkIGZsdWVuY3kgbWVhc3VyZXMgYXNzb2NpYXRlZCB3aXRoIGNvZ25pdGl2ZSwgc29tYXRpYywgYW5kIGJlaGF2aW9yYWwgc3BlYWtpbmcgYW54aWV0eT8KCi0gICBSUTI6IFRvIHdoYXQgZXh0ZW50IGFyZSBicmVha2Rvd24gZmx1ZW5jeSBtZWFzdXJlcyBhc3NvY2lhdGVkIHdpdGggY29nbml0aXZlLCBzb21hdGljLCBhbmQgYmVoYXZpb3JhbCBzcGVha2luZyBhbnhpZXR5PwoKLSAgIFJRMzogVG8gd2hhdCBleHRlbnQgYXJlIHJlcGFpciBmbHVlbmN5IG1lYXN1cmVzIGFzc29jaWF0ZWQgd2l0aCBjb2duaXRpdmUsIHNvbWF0aWMsIGFuZCBiZWhhdmlvcmFsIHNwZWFraW5nIGFueGlldHk/CgpJbiB0aGUgZm9sbG93aW5nIHNlY3Rpb25zLCBJIHByZXByb2Nlc3MgZGF0YSwgY29uZHVjdCBwcmVsaW1pbmFyeSBhbmFseXNlcywgYW5kIGNvbnN0cnVjdCByZWdyZXNzaW9uIG1vZGVscy4KClRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBsb2FkcyBSIHBhY2thZ2VzIHJlcXVpcmVkIGZvciBhbmFseXNlcy4KCmBgYHtyfQpwYWNtYW46OnBfbG9hZCgKICB0aWR5dmVyc2UsIGhlcmUsIHNraW1yLCBwc3ljaCwgCiAgUGVyZm9ybWFuY2VBbmFseXRpY3MsIHNqUGxvdCwgcGVyZm9ybWFuY2UKKQpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgMi4gRGF0YSBQcmVwcm9jZXNzCgpUaGlzIHNlY3Rpb24gdGlkaWVzIGRhdGEuIEZpcnN0IG9mIGFsbCwgdGhlIGZvbGxvd2luZyBjb2RlIGJsb2NrIGxvYWRzIGRhdGEgb2YgVUYgbWVhc3VyZXMuCgpgYGB7cn0KZGZfdWZfcmF3IDwtIHJlYWQuY3N2KGhlcmUoImRhdGEiLCAicHJvY2Vzc2VkIiwgInVmX21lYXN1cmVzLmNzdiIpKQpgYGAKClRoZSBjdXJyZW50IGFuYWx5c2lzIGZvY3VzZXMgb24gdGhlIFVGIG1lYXN1cmVzIHNob3duIGluIFRhYmxlIDEuCgpUYWJsZSAxLiBVRiBEaW1lbnNpb24gYW5kIENvcnJlc3BvbmRpbmcgTWVhc3VyZXMKCnwgVUYgRGltZW5zaW9uICAgICAgICAgICAgfCBNZWFzdXJlICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18CnwgU3BlZWQgRmx1ZW5jeSAoU0YpICAgICAgfCBBcnRpY3VsYXRpb24gUmF0ZSAoQVIpICAgICAgICAgICB8CnwgQnJlYWtkb3duIEZsdWVuY3kgKEJERikgfCBNaWQtQ2xhdXNlIFBhdXNlIFJhdGlvIChNQ1BSKSAgICB8CnwgICAgICAgICAgICAgICAgICAgICAgICAgfCBFbmQtQ2xhdXNlIFBhdXNlIFJhdGlvIChFQ1BSKSAgICB8CnwgICAgICAgICAgICAgICAgICAgICAgICAgfCBNaWQtQ2xhdXNlIFBhdXNlIER1cmF0aW9uIChNQ1BEKSB8CnwgICAgICAgICAgICAgICAgICAgICAgICAgfCBFbmQtQ2xhdXNlIFBhdXNlIER1cmF0aW9uIChFQ1BEKSB8CnwgUmVwYWlyIEZsdWVuY3kgKFJGKSAgICAgfCBEaXNmbHVlbmN5IFJhdGlvICAgICAgICAgICAgICAgICB8CgpUaHVzLCB0aGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgc2VsZWN0cyB0YXJnZXQgbWVhc3VyZXMuIFRoZSBjb2RlIGJsb2NrIGFsc28gcmVuYW1lcyB0aGUgY29sdW1ucyBgZmlsZW5hbWVgIGFuZCBgZHlzZmx1ZW5jeV9yYXRpb2AgdG8gYHBhcnRpY2lwYW50X2lkYCBhbmQgYGRpc2ZsdWVuY3lfcmF0aW9gLCByZXNwZWN0aXZlbHkuCgpgYGB7cn0KZGZfdWZfcmF3ICU+JQogIHNlbGVjdCgKICAgIGZpbGVuYW1lLAogICAgYXJ0aWN1bGF0aW9uX3JhdGUsCiAgICBtaWRfY2xhdXNlX3BhdXNlX3JhdGlvLAogICAgZW5kX2NsYXVzZV9wYXVzZV9yYXRpbywKICAgIG1pZF9jbGF1c2VfcC5kdXIsCiAgICBlbmRfY2xhdXNlX3AuZHVyLAogICAgZHlzZmx1ZW5jeV9yYXRpbwogICkgJT4lCiAgcmVuYW1lKAogICAgcGFydGljaXBhbnRfaWQgPSBmaWxlbmFtZSwKICAgIGRpc2ZsdWVuY3lfcmF0aW8gPSBkeXNmbHVlbmN5X3JhdGlvCiAgKSAtPiBkZl91Zl90aWR5CgpkZl91Zl90aWR5CmBgYAoKTmV4dCwgdGhlIGZvbGxvd2luZyBjb2RlIGJsb2NrIGxvYWRzIGRhdGEgb2YgcG9zdCBxdWVzdGlvbm5haXJlIGFib3V0IGFueGlldHkgYW5kIGxpbmd1aXN0aWMgYmFja2dyb3VuZC4KCmBgYHtyfQpkZl9xdWVzdGlvbm5haXJlX3JhdyA8LSByZWFkLmNzdigKICBoZXJlKCJkYXRhIiwgInJhdyIsICJwb3N0X3F1ZXN0aW9ubmFpcmUuY3N2IikKKQpgYGAKClRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBzZWxlY3RzIGNvbHVtbnMgcmVsYXRlZCB0byBwYXJ0aWNpcGFudCBJRCwgYW54aWV0eSwgTDIgRW5nbGlzaCBwcm9maWNpZW5jeSwgYW5kIG90aGVyIGJhY2tncm91bmRzIGFuZCByZW5hbWVzIHRoZW0uCgpgYGB7cn0KZGZfcXVlc3Rpb25uYWlyZV9yYXcgJT4lCiAgc2VsZWN0KAogICAg5Y+C5Yqg6ICFSUTjgpLlhaXlipvjgZfjgabjgY/jgaDjgZXjgYQu5Y2K6KeSLi4sCiAgICDoi7Hoqp7jgpLoqbHjgZnjgajjgY0u56eB44Gv6KiA6JGJ44KS6ZaT6YGV44GI44Gm44GX44G+44GG44Gu44Gn44Gv44Go44GX44Gw44GX44Gw5b+D6YWN44Gr44Gq44KLLiwKICAgIOiLseiqnuOCkuipseOBmeOBqOOBjS7np4Hjga/oh6rliIbjga7oqbHjgZfmlrnjgYzku5bkurrjgojjgorliqPjgaPjgabjgYTjgovjga7jgafjga/jgajjgZfjgbDjgZfjgbDlv4PphY3jgavjgarjgosuLAogICAg6Iux6Kqe44KS6Kmx44GX5aeL44KB44KL44Go44GZ44GQ44GrLuengeOBr+iHquWIhuiHqui6q+OBruOBk+OBqOOCkuihqOePvuOBp+OBjeOBquOBhOOBruOBp+OBr+OBqOW/g+mFjeOBq+OBquOCiuWni+OCgeOCiy4sCiAgICDoi7Hoqp7jgpLoqbHjgZnjgajjgY0u56eB44Gv44OJ44Kt44OJ44Kt44GZ44KL44GT44Go44GM44KI44GP44GC44KLLiwKICAgIOiLseiqnuOCkuipseOBmeOBqOOBjS7np4Hjga/nt4rlvLXjgafjgbPjgY/jgbPjgY/jgZnjgovjgZPjgajjgYzjgojjgY/jgYLjgosuLAogICAg6Iux6Kqe44KS6Kmx44GZ44Go44GNLuengeOBr+OCiOOBj+axl+OCkuOBi+OBhOOBn+OCii7nmbrmsZfjgZnjgosuLAogICAg6Iux6Kqe44K544OU44O844Kt44Oz44Kw44Gu57e057+S44KS44GZ44KL44Go44GNLuengeOBr+OBl+OBsOOBl+OBsC7jgZnjgZDjgavmipXjgZLlh7rjgZfjgabjgZfjgb7jgYYuLAogICAg56eB44Gv6Iux6Kqe44K544OU44O844Kt44Oz44Kw44Gu57e057+S44Gu5omL44KS5oqc44GP44GT44Go44GM5aSa44GELiwKICAgIOengeOBr+aZruautS7mpbXlipvoi7Hoqp7jgpLoqbHjgZXjgarjgYTjgojjgYbjgavjgZfjgabjgYTjgosuLAogICAg44GK5oyB44Gh44Gn44GX44Gf44KJLuiLseaknOOBruOCueOCs+OCouOCkuiomOWFpeOBl+OBpuOBj+OBoOOBleOBhC4sCiAgICDjgYrmjIHjgaHjgafjgZfjgZ/jgokuSUVMVFMuLk92ZXJhbGwuLuOBruOCueOCs+OCouOCkuiomOWFpeOBl+OBpuOBj+OBoOOBleOBhC4sCiAgICDjgYrmjIHjgaHjgafjgZfjgZ/jgokuVE9FRkwuaUJULuOBruOCueOCs+OCouOCkuiomOWFpeOBl+OBpuOBj+OBoOOBleOBhC4sCiAgICDjgYrmjIHjgaHjgafjgZfjgZ/jgokuVE9FSUMu44Gu44K544Kz44Ki44KS6KiY5YWl44GX44Gm44GP44Gg44GV44GELiwKICAgIOaAp+WIpSwKICAgIOW5tOm9ogogICkgJT4lCiAgcmVuYW1lKAogICAgcGFydGljaXBhbnRfaWQgPSDlj4LliqDogIVJROOCkuWFpeWKm+OBl+OBpuOBj+OBoOOBleOBhC7ljYrop5IuLiwKICAgIGNvZ25pdGl2ZV9hbnhpZXR5XzEgPSDoi7Hoqp7jgpLoqbHjgZnjgajjgY0u56eB44Gv6KiA6JGJ44KS6ZaT6YGV44GI44Gm44GX44G+44GG44Gu44Gn44Gv44Go44GX44Gw44GX44Gw5b+D6YWN44Gr44Gq44KLLiwKICAgIGNvZ25pdGl2ZV9hbnhpZXR5XzIgPSDoi7Hoqp7jgpLoqbHjgZnjgajjgY0u56eB44Gv6Ieq5YiG44Gu6Kmx44GX5pa544GM5LuW5Lq644KI44KK5Yqj44Gj44Gm44GE44KL44Gu44Gn44Gv44Go44GX44Gw44GX44Gw5b+D6YWN44Gr44Gq44KLLiwKICAgIGNvZ25pdGl2ZV9hbnhpZXR5XzMgPSDoi7Hoqp7jgpLoqbHjgZflp4vjgoHjgovjgajjgZnjgZDjgasu56eB44Gv6Ieq5YiG6Ieq6Lqr44Gu44GT44Go44KS6KGo54++44Gn44GN44Gq44GE44Gu44Gn44Gv44Go5b+D6YWN44Gr44Gq44KK5aeL44KB44KLLiwKICAgIHNvbWF0aWNfYW54aWV0eV8xID0g6Iux6Kqe44KS6Kmx44GZ44Go44GNLuengeOBr+ODieOCreODieOCreOBmeOCi+OBk+OBqOOBjOOCiOOBj+OBguOCiy4sCiAgICBzb21hdGljX2FueGlldHlfMiA9IOiLseiqnuOCkuipseOBmeOBqOOBjS7np4Hjga/nt4rlvLXjgafjgbPjgY/jgbPjgY/jgZnjgovjgZPjgajjgYzjgojjgY/jgYLjgosuLAogICAgc29tYXRpY19hbnhpZXR5XzMgPSDoi7Hoqp7jgpLoqbHjgZnjgajjgY0u56eB44Gv44KI44GP5rGX44KS44GL44GE44Gf44KKLueZuuaxl+OBmeOCiy4sCiAgICBiZWhhdmlvcmFsX2FueGlldHlfMSA9IOiLseiqnuOCueODlOODvOOCreODs+OCsOOBrue3tOe/kuOCkuOBmeOCi+OBqOOBjS7np4Hjga/jgZfjgbDjgZfjgbAu44GZ44GQ44Gr5oqV44GS5Ye644GX44Gm44GX44G+44GGLiwKICAgIGJlaGF2aW9yYWxfYW54aWV0eV8yID0g56eB44Gv6Iux6Kqe44K544OU44O844Kt44Oz44Kw44Gu57e057+S44Gu5omL44KS5oqc44GP44GT44Go44GM5aSa44GELiwKICAgIGJlaGF2aW9yYWxfYW54aWV0eV8zID0g56eB44Gv5pmu5q61LualteWKm+iLseiqnuOCkuipseOBleOBquOBhOOCiOOBhuOBq+OBl+OBpuOBhOOCiy4sCiAgICBJRUxUUyA9IOOBiuaMgeOBoeOBp+OBl+OBn+OCiS5JRUxUUy4uT3ZlcmFsbC4u44Gu44K544Kz44Ki44KS6KiY5YWl44GX44Gm44GP44Gg44GV44GELiwKICAgIFRPRUZMX0lCVCA9IOOBiuaMgeOBoeOBp+OBl+OBn+OCiS5UT0VGTC5pQlQu44Gu44K544Kz44Ki44KS6KiY5YWl44GX44Gm44GP44Gg44GV44GELiwKICAgIFRPRUlDID0g44GK5oyB44Gh44Gn44GX44Gf44KJLlRPRUlDLuOBruOCueOCs+OCouOCkuiomOWFpeOBl+OBpuOBj+OBoOOBleOBhC4sCiAgICBlaWtlbiA9IOOBiuaMgeOBoeOBp+OBl+OBn+OCiS7oi7HmpJzjga7jgrnjgrPjgqLjgpLoqJjlhaXjgZfjgabjgY/jgaDjgZXjgYQuLAogICAgc2V4ID0g5oCn5YilLAogICAgYWdlID0g5bm06b2iCiAgKSAlPiUKICBtdXRhdGUoCiAgICBzZXggPSBzdHJfcmVwbGFjZV9hbGwoc2V4LCAi55S35oCnIiwgIm1hbGUiKSwKICAgIHNleCA9IHN0cl9yZXBsYWNlX2FsbChzZXgsICLlpbPmgKciLCAiZmVtYWxlIiksCiAgICBlaWtlbiA9IHN0cl9yZXBsYWNlX2FsbChlaWtlbiwgIua6ljHntJoiLCAiMS41IiksCiAgICBlaWtlbiA9IHN0cl9yZXBsYWNlX2FsbChlaWtlbiwgIua6lu+8kee0miIsICIxLjUiKSwKICAgIGVpa2VuID0gc3RyX3JlcGxhY2VfYWxsKGVpa2VuLCAiMue0miIsICIyIiksCiAgICBlaWtlbiA9IHN0cl9yZXBsYWNlX2FsbChlaWtlbiwgIjHntJoiLCAiMSIpLAogICAgZWlrZW4gPSBzdHJfcmVwbGFjZV9hbGwoZWlrZW4sICLoi7HmpJw057SaIiwgIjQiKSwKICAgIGVpa2VuID0gYXMubnVtZXJpYyhlaWtlbikKICApIC0+IGRmX3F1ZXN0aW9ubmFpcmVfdGlkeQoKZGZfcXVlc3Rpb25uYWlyZV90aWR5CmBgYAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyAzLiBQcmVsaW1pbmFyeSBBbmFseXNpcwoKIyMjIDMuMS4gUGFydGljaXBhbnQgQmFja2dyb3VuZAoKVGhlIGZvbGxvd2luZyBjb2RlIGJsb2NrIGNhbGN1bGF0ZXMgdGhlIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3Mgb2YgcGFydGljaXBhbnRzJyBhZ2UuCgpgYGB7cn0KZGZfcXVlc3Rpb25uYWlyZV90aWR5ICU+JQogIHNlbGVjdChhZ2UpICU+JQogIHNraW0oKQpgYGAKClRoZSByZXN1bHQgc2hvd2VkIHRoYXQgcGFydGljaXBhbnRzJyBhZ2Ugd2FzIHJhbmdlZCAkWzIwLCAzOF0kLCBhbmQgdGhlaXIgbWVhbiBhbmQgU0Qgd2VyZSAkMjguOCQgYW5kICQ1LjYxMyQuCgpUaGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgY291bnRzIHNleCBvZiBwYXJ0aWNpcGFudHMuCgpgYGB7cn0KZGZfcXVlc3Rpb25uYWlyZV90aWR5ICU+JQogIGdyb3VwX2J5KHNleCkgJT4lCiAgc3VtbWFyaXplKE4gPSBuKCkpCmBgYAoKVGhlIHJlc3VsdCBpbmRpY2F0ZWQgdGhhdCB0aGVyZSB3ZXJlIGVxdWFsIG51bWJlciBvZiBtYWxlIGFuZCBmZW1hbGUgcGFydGljaXBhbnRzLgoKIyMjIDMuMi4gUHJvZmljaWVuY3kgTGV2ZWxzCgpUaGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgY29udmVydHMgTDIgRW5nbGlzaCBhc3Nlc3NtZW50IHNjb3JlcyB0byBDRUZSLgoKYGBge3J9CmNlZnJfbGV2ZWxzID0gYygiQTEiLCAiQTIiLCAiQjEiLCAiQjIiLCAiQzEiLCAiQzIiKQoKZGZfcXVlc3Rpb25uYWlyZV90aWR5ICU+JQogIHNlbGVjdChwYXJ0aWNpcGFudF9pZCwgVE9FRkxfSUJULCBJRUxUUywgVE9FSUMsIGVpa2VuKSAlPiUKICBtdXRhdGUoCiAgICBUT0VGTF9JQlQgPSBjYXNlX3doZW4oCiAgICAgIFRPRUZMX0lCVCA+PSAxMTQgfiAiQzIiLAogICAgICBUT0VGTF9JQlQgPj0gOTUgfiAiQzEiLAogICAgICBUT0VGTF9JQlQgPj0gNzIgfiAiQjIiCiAgICApLAogICAgSUVMVFMgPSBjYXNlX3doZW4oCiAgICAgIElFTFRTID49IDcgfiAiQzEiCiAgICApLAogICAgVE9FSUMgPSBjYXNlX3doZW4oCiAgICAgIFRPRUlDID49IDk0NSB+ICJDMSIsCiAgICAgIFRPRUlDID49IDc4NSB+ICJCMSIsCiAgICAgIFRPRUlDID49IDU1MCB+ICJCMiIKICAgICksCiAgICBlaWtlbiA9IGNhc2Vfd2hlbigKICAgICAgZWlrZW4gPj0gMyB+ICJBMSIsCiAgICAgIGVpa2VuID49IDIgfiAiQjEiLAogICAgICBlaWtlbiA+PSAxLjUgfiAiQjIiLAogICAgICBlaWtlbiA+PSAxIH4gIkMxIgogICAgKQogICkgJT4lCiAgbXV0YXRlKAogICAgVE9FRkxfSUJUID0gZmFjdG9yKFRPRUZMX0lCVCwgbGV2ZWxzID0gY2Vmcl9sZXZlbHMsIG9yZGVyID0gVCksCiAgICBJRUxUUyA9IGZhY3RvcihJRUxUUywgbGV2ZWxzID0gY2Vmcl9sZXZlbHMsIG9yZGVyID0gVCksCiAgICBUT0VJQyA9IGZhY3RvcihUT0VJQywgbGV2ZWxzID0gY2Vmcl9sZXZlbHMsIG9yZGVyID0gVCksCiAgICBlaWtlbiA9IGZhY3RvcihlaWtlbiwgbGV2ZWxzID0gY2Vmcl9sZXZlbHMsIG9yZGVyID0gVCkKICApICU+JSAKICByZXBsYWNlX25hKGxpc3QoCiAgICBUT0VGTF9JQlQgPSAiQTEiLAogICAgSUVMVFMgPSAiQTEiLAogICAgVE9FSUMgPSAiQTEiLAogICAgZWlrZW4gPSAiQTEiCiAgKSkgJT4lCiAgZ3JvdXBfYnkocGFydGljaXBhbnRfaWQpICU+JQogIHN1bW1hcml6ZShDRUZSID0gbWF4KFRPRUZMX0lCVCwgSUVMVFMsIFRPRUlDLCBlaWtlbikpICU+JQogIGdyb3VwX2J5KENFRlIpICU+JQogIHN1bW1hcml6ZShOID0gbigpKQpgYGAKClRoZSByZXN1bHQgc3VnZ2VzdGVkIHRoYXQgbW9zdCBwYXJ0aWNpcGFudHMgd2VyZSBhZHZhbmNlZC1sZXZlbCBMMiBFbmdsaXNoIGxlYXJuZXJzICgkTj02JCksIHdoaWxlIG90aGVyIGZvdXIgcGFydGljaXBhbnRzIHdlcmUgaW50ZXJtZWRpYXRlLWxldmVsIEVuZ2xpc2ggbGVhcm5lcnMuCgojIyMgMy4zLiBVRiBNZWFzdXJlcwoKVGhlIGZvbGxvd2luZyBjb2RlIGJsb2NrIGNhbGN1bGF0ZXMgdGhlIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3Mgb2YgVUYgbWVhc3VyZXMuCgpgYGB7cn0KZGZfdWZfdGlkeSAlPiUKICBzZWxlY3QoLWMocGFydGljaXBhbnRfaWQpKSAlPiUKICBza2ltKCkKYGBgCgojIyMgMy40LiBTcGVha2luZyBBbnhpZXR5CgpUaGUgZm9sbG93aW5nIGNvZGUgYmxvY2tzIGNhbGN1bGF0ZSB0aGUgcmVsaWFiaWxpdHkgb2YgYW54aWV0eSBxdWVzdGlvbm5haXJlIGFuc3dlcnMgaW4gdGVybXMgb2YgQ3JvbmJhY2gncyAkXGFscGhhJC4KCiMjIyMgKjMuNC4xLiBSZWxpYWJpbGl0eSBvZiBDb2duaXRpdmUgQW54aWV0eSoKCmBgYHtyfQpkZl9xdWVzdGlvbm5haXJlX3RpZHkgJT4lIAogIHNlbGVjdCgKICAgIGNvZ25pdGl2ZV9hbnhpZXR5XzEsCiAgICBjb2duaXRpdmVfYW54aWV0eV8yLAogICAgY29nbml0aXZlX2FueGlldHlfMwogICkgJT4lCiAgYWxwaGEoKQpgYGAKClRoZSBDb3JuYmFjaCdzICRcYWxwaGEkIG9mIGNvZ25pdGl2ZSBhbnhpZXR5IHF1ZXN0aW9ubmFpcmVzIHdhcyAkLjc0NyQsIGluZGljYXRpbmcgYW4gYWNjZXB0YWJsZSBpbnRlcm5hbCBjb25zaXN0ZW5jeQoKIyMjIyAqMy40LjIuIFJlbGlhYmlsaXR5IG9mIFNvbWF0aWMgQW54aWV0eSoKCmBgYHtyfQpkZl9xdWVzdGlvbm5haXJlX3RpZHkgJT4lIAogIHNlbGVjdCgKICAgIHNvbWF0aWNfYW54aWV0eV8xLAogICAgc29tYXRpY19hbnhpZXR5XzIsCiAgICBzb21hdGljX2FueGlldHlfMwogICkgJT4lCiAgYWxwaGEoKQpgYGAKClRoZSBDb3JuYmFjaCdzICRcYWxwaGEkIG9mIHNvbWF0aWMgYW54aWV0eSBxdWVzdGlvbm5haXJlcyB3YXMgJC45MDAkLCBpbmRpY2F0aW5nIGEgZXhjZWxsZW50IGludGVybmFsIGNvbnNpc3RlbmN5LgoKIyMjIyAzLjQuMy4gQmVoYXZpb3JhbCBBbnhpZXR5CgpgYGB7cn0KZGZfcXVlc3Rpb25uYWlyZV90aWR5ICU+JSAKICBzZWxlY3QoCiAgICBiZWhhdmlvcmFsX2FueGlldHlfMSwKICAgIGJlaGF2aW9yYWxfYW54aWV0eV8yLAogICAgYmVoYXZpb3JhbF9hbnhpZXR5XzMKICApICU+JQogIGFscGhhKCkKYGBgCgpUaGUgQ29ybmJhY2gncyAkXGFscGhhJCBvZiBzb21hdGljIGFueGlldHkgcXVlc3Rpb25uYWlyZXMgd2FzICQuODE0JCwgaW5kaWNhdGluZyBhIGdvb2QgaW50ZXJuYWwgY29uc2lzdGVuY3kuCgojIyMgMy41LiBDb3JyZWxhdGlvbnMKClRoaXMgc3Vic2VjdGlvbiBjb25kdWN0cyBjb3JyZWxhdGlvbiBhbmFseXNlcyBiZXR3ZWVuIFVGIG1lYXN1cmVzIGFuZCBzcGVha2luZyBhbnhpZXR5LiBCZWZvcmUgdGhlIGFuYWx5c2VzLCB0aGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgY2FsY3VsYXRlcyB0aHJlZSBhbnhpZXR5IHNjb3JlcyBieSBzdW1taW5nIGl0ZW1zIGFuZCBqb2lucyB0aGUgdHdvIGRhdGFmcmFtZXMuCgpgYGB7cn0KZGZfcXVlc3Rpb25uYWlyZV90aWR5ICU+JQogIGdyb3VwX2J5KHBhcnRpY2lwYW50X2lkKSAlPiUKICBzdW1tYXJpemUoCiAgICBjb2duaXRpdmVfYW54aWV0eSA9IHN1bSgKICAgICAgY29nbml0aXZlX2FueGlldHlfMSwgY29nbml0aXZlX2FueGlldHlfMiwgY29nbml0aXZlX2FueGlldHlfMwogICAgKSwKICAgIHNvbWF0aWNfYW54aWV0eSA9IHN1bSgKICAgICAgc29tYXRpY19hbnhpZXR5XzEsIHNvbWF0aWNfYW54aWV0eV8yLCBzb21hdGljX2FueGlldHlfMwogICAgKSwKICAgIGJlaGF2aW9yYWxfYW54aWV0eSA9IHN1bSgKICAgICAgYmVoYXZpb3JhbF9hbnhpZXR5XzEsIGJlaGF2aW9yYWxfYW54aWV0eV8yLCBiZWhhdmlvcmFsX2FueGlldHlfMwogICAgKQogICkgJT4lIAogIGlubmVyX2pvaW4oCiAgICBkZl91Zl90aWR5LCBieSA9ICJwYXJ0aWNpcGFudF9pZCIKICApIC0+IGRmX3VmX2FueGlldHkKCmRmX3VmX2FueGlldHkKYGBgCgojIyMjIDMuNS4xLiBDb3JyZWxhdGlvbnMgQW1vbmcgQW54aWV0eSBTY29yZXMKClRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBnZW5lcmF0ZXMgYSBjb3JyZWxhdGlvbiBtYXRyaXggb2YgdGhyZWUgYW54aWV0eSBzY29yZXMuCgpgYGB7cn0KZGZfdWZfYW54aWV0eSAlPiUKICBzZWxlY3QoCiAgICBjb2duaXRpdmVfYW54aWV0eSwKICAgIHNvbWF0aWNfYW54aWV0eSwKICAgIGJlaGF2aW9yYWxfYW54aWV0eQogICkgJT4lCiAgY2hhcnQuQ29ycmVsYXRpb24oaGlzdG9ncmFtID0gVCwgbWV0aG9kID0gInBlYXJzb24iLCBwY2ggPSAxOSkKYGBgCgpUaGUgcmVzdWx0IHNob3dlZCB0aGF0IHNpZ25pZmljYW50IHN0cm9uZyBjb3JyZWxhdGlvbiBiZXR3ZWVuIGNvZ25pdGl2ZSBhbmQgc29tYXRpYyBhbnhpZXR5ICgkcj0uNzgkKS4gSW4gYWRkaXRpb24sIHRoZXJlIHdhcyBzbGlnaHRseSBzaWduaWZpY2FudCBtZWRpdW0gY29ycmVsYXRpb24gYmV0d2VlbiBzb21hdGljIGFuZCBiZWhhdmlvcmFsIGFueGlldHkgKCRyPS41OSQpLiBNZWFud2hpbGUsIHRoZXJlIHdhcyBzbWFsbCBjb3JyZWxhdGlvbiBiZXR3ZWVuIGNvZ25pdGl2ZSBhbmQgYmVoYXZpb3JhbCBhbnhpZXR5ICgkcj0uNDgkKSwgYnV0IHN0YXRpc3RpY2FsIHNpZ25pZmljYW5jZSB3YXMgbm90IGZvdW5kLgoKIyMjIyAzLjUuMi4gQ29ycmVsYXRpb25zIEJldHdlZW4gVUYgTWVhc3VyZXMgYW5kIENvZ25pdGl2ZSBBbnhpZXR5CgpUaGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgZ2VuZXJhdGVzIGEgY29ycmVsYXRpb24gbWF0cml4IG9mIFVGIG1lYXN1cmVzIGFuZCBjb2duaXRpdmUgYW54aWV0eS4KCmBgYHtyfQpkZl91Zl9hbnhpZXR5ICU+JQogIHNlbGVjdCgtYygKICAgIHBhcnRpY2lwYW50X2lkLCAKICAgIHNvbWF0aWNfYW54aWV0eSwgCiAgICBiZWhhdmlvcmFsX2FueGlldHkKICApKSAlPiUKICBjaGFydC5Db3JyZWxhdGlvbihoaXN0b2dyYW0gPSBULCBtZXRob2QgPSAicGVhcnNvbiIsIHBjaCA9IDE5KQpgYGAKClRoZSByZXN1bHQgc2hvd2VkIHNpZ25pZmljYW50IGxhcmdlIGNvcnJlbGF0aW9uIGJldHdlZW4gY29nbml0aXZlIGFueGlldHkgYW5kIEVDUFIsIHN1Z2dlc3RpbmcgdGhhdCBwYXJ0aWNpcGFudHMgcHJvZHVjZWQgZW5kLWNsYXVzZSBwYXVzZXMgbW9yZSBmcmVxdWVudGx5IHdoZW4gY29nbml0aXZlIGFueGlldHkgd2FzIGxvd2VyLgoKIyMjIyAzLjUuMy4gQ29ycmVsYXRpb25zIEJldHdlZW4gVUYgTWVhc3VyZXMgYW5kIFNvbWF0aWMgQW54aWV0eQoKVGhlIGZvbGxvd2luZyBjb2RlIGJsb2NrIGdlbmVyYXRlcyBhIGNvcnJlbGF0aW9uIG1hdHJpeCBvZiBVRiBtZWFzdXJlcyBhbmQgc29tYXRpYyBhbnhpZXR5LgoKYGBge3J9CmRmX3VmX2FueGlldHkgJT4lCiAgc2VsZWN0KC1jKAogICAgcGFydGljaXBhbnRfaWQsIAogICAgY29nbml0aXZlX2FueGlldHksIAogICAgYmVoYXZpb3JhbF9hbnhpZXR5CiAgKSkgJT4lCiAgY2hhcnQuQ29ycmVsYXRpb24oaGlzdG9ncmFtID0gVCwgbWV0aG9kID0gInBlYXJzb24iLCBwY2ggPSAxOSkKYGBgCgpUaGUgcmVzdWx0IGRpZCBub3Qgc2hvdyBzaWduaWZpY2FudCBjb3JyZWxhdGlvbnMgYmV0d2VlbiBzb21hdGljIGFueGlldHkgYW5kIFVGIG1lYXN1cmVzLgoKIyMjIyAzLjUuNC4gQ29ycmVsYXRpb25zIEJldHdlZW4gVUYgTWVhc3VyZXMgYW5kIEJlaGF2aW9yYWwgQW54aWV0eQoKVGhlIGZvbGxvd2luZyBjb2RlIGJsb2NrIGdlbmVyYXRlcyBhIGNvcnJlbGF0aW9uIG1hdHJpeCBvZiBVRiBtZWFzdXJlcyBhbmQgYmVoYXZpb3JhbCBhbnhpZXR5LgoKYGBge3J9CmRmX3VmX2FueGlldHkgJT4lCiAgc2VsZWN0KC1jKAogICAgcGFydGljaXBhbnRfaWQsIAogICAgY29nbml0aXZlX2FueGlldHksIAogICAgc29tYXRpY19hbnhpZXR5CiAgKSkgJT4lCiAgY2hhcnQuQ29ycmVsYXRpb24oaGlzdG9ncmFtID0gVCwgbWV0aG9kID0gInBlYXJzb24iLCBwY2ggPSAxOSkKYGBgCgpUaGUgcmVzdWx0IGlkZW50aWZpZWQgc2lnbmlmaWNhbnQgbGFyZ2UgY29ycmVsYXRpb25zIGJldHdlZW4gYmVoYXZpb3JhbCBhbnhpZXR5IGFuZCBNQ1BEICgkcj0tLjc2JCkgYW5kIEVDUEQgKCRyPS43OSQpLCBzdWdnZXN0aW5nIHRoYXQgcGFydGljaXBhbnRzIHdobyBwZXJjZWl2ZWQgbG93ZXIgYmVoYXZpb3JhbCBhbnhpZXR5IGdlbmVyYXRlIGxvbmdlciBNQ1BEIGFuZCBFQ1BELgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyA0LiBSZWdyZXNzaW9uIEFuYWx5c2VzCgojIyMgNC4xLiBTRiBcfiBTcGVha2luZyBBbnhpZXR5CgpUaGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgY29uc3RydWN0cyBhIHJlZ3Jlc3Npb24gbW9kZWwgYmV0d2VlbiBBUiBhbmQgc3BlYWtpbmcgYW54aWV0eS4KCmBgYHtyfQptb2RlbF9hciA8LSBsbSgKICBhcnRpY3VsYXRpb25fcmF0ZSB+IGNvZ25pdGl2ZV9hbnhpZXR5ICsgc29tYXRpY19hbnhpZXR5ICsgYmVoYXZpb3JhbF9hbnhpZXR5LAogIGRmX3VmX2FueGlldHkKKQpgYGAKClRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBzaG93cyB0aGUgcmVzdWx0LgoKYGBge3J9CnRhYl9tb2RlbChtb2RlbF9hciwgZGlnaXRzID0gMykKYGBgCgpUaGUgcmVzdWx0IGRpZCBub3Qgc2hvdyBzaWduaWZpY2FudCByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aHJlZSBhbnhpZXR5IHNjb3JlcyBhbmQgQVIuCgpUbyBleGFtaW5lIHRoZSByZWxpYWJpbGl0eSBvZiB0aGUgY3VycmVudCBtb2RlbCwgdGhlIGZvbGxvd2luZyBjb2RlIGJsb2NrIGNvbmR1Y3RzIHBvc3QtaG9jIGFuYWx5c2lzIG9mIHJlZ3Jlc3Npb24gYXNzdW1wdGlvbnMuCgpgYGB7cn0KY2hlY2tfbW9kZWwobW9kZWxfYXIpCmBgYAoKVGhlIHJlc3VsdHMgc3VnZ2VzdGVkIHRoYXQgdGhlIGN1cnJlbnQgbW9kZWwgY291bGQgYmUgcmVsaWFibGUuCgojIyMgNC4yLiBCREYgXH4gU3BlYWtpbmcgQW54aWV0eQoKIyMjIyA0LjIuMS4gTUNQUiBcfiBTcGVha2luZyBBbnhpZXR5CgpUaGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgY29uc3RydWN0cyBhIHJlZ3Jlc3Npb24gbW9kZWwgYmV0d2VlbiBNQ1BSIGFuZCBzcGVha2luZyBhbnhpZXR5LgoKYGBge3J9Cm1vZGVsX21jcHIgPC0gbG0oCiAgbWlkX2NsYXVzZV9wYXVzZV9yYXRpbyB+IGNvZ25pdGl2ZV9hbnhpZXR5ICsgc29tYXRpY19hbnhpZXR5ICsgYmVoYXZpb3JhbF9hbnhpZXR5LAogIGRmX3VmX2FueGlldHkKKQpgYGAKClRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBzaG93cyB0aGUgcmVzdWx0LgoKYGBge3J9CnRhYl9tb2RlbChtb2RlbF9tY3ByLCBkaWdpdHMgPSAzKQpgYGAKClRoZSByZXN1bHQgZGlkIG5vdCBzaG93IHNpZ25pZmljYW50IHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRocmVlIGFueGlldHkgc2NvcmVzIGFuZCBNQ1BSLgoKVG8gZXhhbWluZSB0aGUgcmVsaWFiaWxpdHkgb2YgdGhlIGN1cnJlbnQgbW9kZWwsIHRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBjb25kdWN0cyBwb3N0LWhvYyBhbmFseXNpcyBvZiByZWdyZXNzaW9uIGFzc3VtcHRpb25zLgoKYGBge3J9CmNoZWNrX21vZGVsKG1vZGVsX21jcHIpCmBgYAoKVGhlIHJlc3VsdHMgc3VnZ2VzdGVkIHRoYXQgdGhlIGN1cnJlbnQgbW9kZWwgY291bGQgYmUgbGVzcyByZWxpYWJsZSBiZWNhdXNlIHRoZSBtb2RlbCBjb3VsZCBiZSBhZmZlY3RlZCBieSBhbiBvdXRsaWVyLgoKIyMjIyA0LjIuMi4gRUNQUiBcfiBTcGVha2luZyBBbnhpZXR5CgpUaGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgY29uc3RydWN0cyBhIHJlZ3Jlc3Npb24gbW9kZWwgYmV0d2VlbiBFQ1BSIGFuZCBzcGVha2luZyBhbnhpZXR5LgoKYGBge3J9Cm1vZGVsX2VjcHIgPC0gbG0oCiAgZW5kX2NsYXVzZV9wYXVzZV9yYXRpbyB+IGNvZ25pdGl2ZV9hbnhpZXR5ICsgc29tYXRpY19hbnhpZXR5ICsgYmVoYXZpb3JhbF9hbnhpZXR5LAogIGRmX3VmX2FueGlldHkKKQpgYGAKClRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBzaG93cyB0aGUgcmVzdWx0LgoKYGBge3J9CnRhYl9tb2RlbChtb2RlbF9lY3ByLCBkaWdpdHMgPSAzKQpgYGAKClRoZSByZXN1bHQgc2hvd2VkIHNsaWdodGx5IHNpZ25pZmljYW50IHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGNvZ25pdGl2ZSBhbnhpZXR5IGFuZCBFQ1BSICgkcD0uMDgxJCkuIFRoZSBzbG9wZSB3YXMgJC0uMDAzJCBhbmQgc3VnZ2VzdGVkIHRoYXQgRUNQUiBkZWNyZWFzZWQgJC4wMDMkIHdoZW4gY29nbml0aXZlIGFueGlldHkgaW5jcmVhc2VkICQxJC4KClRvIGV4YW1pbmUgdGhlIHJlbGlhYmlsaXR5IG9mIHRoZSBjdXJyZW50IG1vZGVsLCB0aGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgY29uZHVjdHMgcG9zdC1ob2MgYW5hbHlzaXMgb2YgcmVncmVzc2lvbiBhc3N1bXB0aW9ucy4KCmBgYHtyfQpjaGVja19tb2RlbChtb2RlbF9lY3ByKQpgYGAKClRoZSByZXN1bHRzIHN1Z2dlc3RlZCB0aGF0IHRoZSBjdXJyZW50IG1vZGVsIGNvdWxkIGJlIHJlbGlhYmxlLgoKIyMjIyA0LjIuMy4gTUNQRCBcfiBTcGVha2luZyBBbnhpZXR5CgpUaGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgY29uc3RydWN0cyBhIHJlZ3Jlc3Npb24gbW9kZWwgYmV0d2VlbiBNQ1BEIGFuZCBzcGVha2luZyBhbnhpZXR5LgoKYGBge3J9Cm1vZGVsX21jcGQgPC0gbG0oCiAgbWlkX2NsYXVzZV9wLmR1ciB+IGNvZ25pdGl2ZV9hbnhpZXR5ICsgc29tYXRpY19hbnhpZXR5ICsgYmVoYXZpb3JhbF9hbnhpZXR5LAogIGRmX3VmX2FueGlldHkKKQpgYGAKClRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBzaG93cyB0aGUgcmVzdWx0LgoKYGBge3J9CnRhYl9tb2RlbChtb2RlbF9tY3BkLCBkaWdpdHMgPSAzKQpgYGAKClRoZSByZXN1bHQgc2hvd2VkIGEgc2lnbmlmaWNhbnQgbGluayBiZXR3ZWVuIGJlaGF2aW9yYWwgYW54aWV0eSBhbmQgTUNQRCAoJHA9LjAyNSQpLiBUaGUgc2xvcGUgd2FzICQtLjA3NCQsIHN1Z2dlc3RpbmcgdGhhdCBNQ1BEIGJlY2FtZSAkLjA3NCQgc2hvcnRlciB3aGVuIGJlaGF2aW9yYWwgYW54aWV0eSBzY29yZSBpbmNyZWFzZWQgJDEkLgoKVG8gZXhhbWluZSB0aGUgcmVsaWFiaWxpdHkgb2YgdGhlIGN1cnJlbnQgbW9kZWwsIHRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBjb25kdWN0cyBwb3N0LWhvYyBhbmFseXNpcyBvZiByZWdyZXNzaW9uIGFzc3VtcHRpb25zLgoKYGBge3J9CmNoZWNrX21vZGVsKG1vZGVsX21jcGQpCmBgYAoKVGhlIHJlc3VsdHMgc3VnZ2VzdGVkIHRoYXQgdGhlIGN1cnJlbnQgbW9kZWwgY291bGQgYmUgcmVsaWFibGUuCgojIyMjIDQuMi40LiBFQ1BEIFx+IFNwZWFraW5nIEFueGlldHkKClRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBjb25zdHJ1Y3RzIGEgcmVncmVzc2lvbiBtb2RlbCBiZXR3ZWVuIEFSIGFuZCBzcGVha2luZyBhbnhpZXR5LgoKYGBge3J9Cm1vZGVsX2VjcGQgPC0gbG0oCiAgZW5kX2NsYXVzZV9wLmR1ciB+IGNvZ25pdGl2ZV9hbnhpZXR5ICsgc29tYXRpY19hbnhpZXR5ICsgYmVoYXZpb3JhbF9hbnhpZXR5LAogIGRmX3VmX2FueGlldHkKKQpgYGAKClRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBzaG93cyB0aGUgcmVzdWx0LgoKYGBge3J9CnRhYl9tb2RlbChtb2RlbF9lY3BkLCBkaWdpdHMgPSAzKQpgYGAKClRoZSByZXN1bHQgc2hvd2VkIGEgc2lnbmlmaWNhbnQgbGluayBiZXR3ZWVuIGJlaGF2aW9yYWwgYW54aWV0eSBhbmQgTUNQRCAoJHA9LjAyMCQpLiBUaGUgc2xvcGUgd2FzICQtLjA3MiQsIHN1Z2dlc3RpbmcgdGhhdCBFQ1BEIGJlY2FtZSAkLjA3MiQgc2hvcnRlciB3aGVuIGJlaGF2aW9yYWwgYW54aWV0eSBzY29yZSBpbmNyZWFzZWQgJDEkLgoKVG8gZXhhbWluZSB0aGUgcmVsaWFiaWxpdHkgb2YgdGhlIGN1cnJlbnQgbW9kZWwsIHRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBjb25kdWN0cyBwb3N0LWhvYyBhbmFseXNpcyBvZiByZWdyZXNzaW9uIGFzc3VtcHRpb25zLgoKYGBge3J9CmNoZWNrX21vZGVsKG1vZGVsX2VjcGQpCmBgYAoKVGhlIHJlc3VsdHMgc3VnZ2VzdGVkIHRoYXQgdGhlIGN1cnJlbnQgbW9kZWwgY291bGQgYmUgcmVsaWFibGUuCgojIyMgNC4zLiBSRiBcfiBTcGVha2luZyBBbnhpZXR5CgpUaGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgY29uc3RydWN0cyBhIHJlZ3Jlc3Npb24gbW9kZWwgYmV0d2VlbiBEUiBhbmQgc3BlYWtpbmcgYW54aWV0eS4KCmBgYHtyfQptb2RlbF9kciA8LSBsbSgKICBkaXNmbHVlbmN5X3JhdGlvIH4gY29nbml0aXZlX2FueGlldHkgKyBzb21hdGljX2FueGlldHkgKyBiZWhhdmlvcmFsX2FueGlldHksCiAgZGZfdWZfYW54aWV0eQopCmBgYAoKVGhlIGZvbGxvd2luZyBjb2RlIGJsb2NrIHNob3dzIHRoZSByZXN1bHQuCgpgYGB7cn0KdGFiX21vZGVsKG1vZGVsX2RyLCBkaWdpdHMgPSAzKQpgYGAKClRoZSByZXN1bHQgZGlkIG5vdCBzaG93IHNpZ25pZmljYW50IHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRocmVlIGFueGlldHkgc2NvcmVzIGFuZCBEUi4KClRvIGV4YW1pbmUgdGhlIHJlbGlhYmlsaXR5IG9mIHRoZSBjdXJyZW50IG1vZGVsLCB0aGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgY29uZHVjdHMgcG9zdC1ob2MgYW5hbHlzaXMgb2YgcmVncmVzc2lvbiBhc3N1bXB0aW9ucy4KCmBgYHtyfQpjaGVja19tb2RlbChtb2RlbF9kcikKYGBgCgpUaGUgcmVzdWx0cyBzdWdnZXN0ZWQgdGhhdCB0aGUgY3VycmVudCBtb2RlbCBjb3VsZCBiZSBsZXNzIHJlbGlhYmxlIGJlY2F1c2UgdGhlIG1vZGVsIGNvdWxkIGJlIGFmZmVjdGVkIGJ5IGFuIG91dGxpZXIuCgojIyMgCg==